Skip to content

fix(oauth): harden xAI Retry-After and abort handling - #4060

Draft
chilung-cgu wants to merge 2 commits into
lidge-jun:devfrom
chilung-cgu:fix/xai-oauth-retry-after
Draft

fix(oauth): harden xAI Retry-After and abort handling#4060
chilung-cgu wants to merge 2 commits into
lidge-jun:devfrom
chilung-cgu:fix/xai-oauth-retry-after

Conversation

@chilung-cgu

@chilung-cgu chilung-cgu commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Summary

Verification

  • /home/ubuntu/.bun/bin/bun test tests/providers/xai/xai-oauth-retry.test.ts — 23 pass / 0 fail.
  • /home/ubuntu/.bun/bin/bun test tests/providers/xai/xai-refresh-lock.test.ts — 10 pass / 0 fail.
  • /home/ubuntu/.bun/bin/bun test tests/oauth/oauth-refresh.test.ts — 55 pass / 0 fail.
  • /home/ubuntu/.bun/bin/bun test tests/codex-integration/combos.test.ts — 77 pass / 0 fail.
  • /home/ubuntu/.bun/bin/bun run typecheck — exit 0.
  • /home/ubuntu/.bun/bin/bun run privacy:scan — passed.
  • git diff --check — clean.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

Review readiness checklist

This PR stays in draft until every box below is ticked. Tick all four boxes once the requirements are met:

  • All CI tests are green on my local testing.
  • I pushed my PR to the latest dev commit.
  • I resolved all correct Codex and CodeRabbit findings.
  • My PR is ready for review.

Honor bounded numeric and HTTP-date retry delays, make backoff cancellation-aware, and preserve caller aborts across response-body and custom sleep races.

Closes lidge-jun#4045

Closes lidge-jun#4046

Closes lidge-jun#4047
@coderabbitai

coderabbitai Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added the intake: hygiene-blocked Deterministic PR hygiene checks failed label Sep 8, 2026
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

⚠️ Deterministic hygiene checks failed.

  • empty_catch — An empty catch block was added. Handle, report, or deliberately propagate the error. Paths: src/oauth/xai.ts.
  • unsponsored_surface — This changes an authentication, workflow, release-automation, or dependency surface. MAINTAINERS.md requires security review for these; ask a maintainer to apply maintainer-sponsored once they have reviewed it. Paths: src/oauth/xai.ts.

@github-actions github-actions Bot added the bug Something isn't working label Sep 8, 2026
@github-actions

github-actions Bot commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

⏳ DRAFT

  • hygiene: unsponsored_surface.

What to do

  • Fix unsponsored_surface — This changes an authentication, workflow, release-automation, or dependency surface. MAINTAINERS.md requires security review for these; ask a maintainer to apply maintainer-sponsored once they have reviewed it. Paths: src/oauth/xai.ts.

Review readiness checklist

  • ✅ All CI tests are green on my local testing.
  • ✅ I pushed my PR to the latest dev commit.
  • ✅ I resolved all correct Codex and CodeRabbit findings.
  • ✅ My PR is ready for review.

4/4 boxes ticked.

This pull request was already a draft. Its draft status will be preserved after every issue above is resolved.

@lidge-jun

lidge-jun commented Sep 8, 2026

Copy link
Copy Markdown
Owner

리뷰 · 우선순위 54 / 80

이 PR은 이슈 #4045 / #4046 / #4047을 한 번에 닫는 xAI OAuth Retry-After·abort 하드닝이다. 작성자는 chilung-cgu, 베이스는 dev, 헤드 1d19c1a47(브랜치 fix/xai-oauth-retry-after), 현재 DRAFT이며 bug + intake: hygiene-blocked 라벨이 있다. 로컬 dev HEAD는 ff524ae63(#4058 wp4), package 2.49.0이다. tip과 겹치는 파일은 주로 src/oauth/xai.ts이고, 같은 파일을 건드리는 형제 PR #4065(엔드포인트 호스트 allow-list, #4048)도 열려 있다. types.ts/config.ts 분할 캠페인과는 무관해서 close-don't-rebase 대상이 아니다. 중복 구현 PR은 검색상 없다(이슈 세 개는 이미 이 PR이 closes로 묶음).

왜 지금 dev에서 의미가 있나. HEAD의 src/oauth/xai.ts retryDelay는 Retry-After를 정수 초만 읽고(/^\d+$/), 그다음 Math.min(2000, …)전부 2초 캡한다. 그래서 (1) 서버가 60이나 1.5를 줘도 2초로 잘리고(#4045), (2) HTTP-date 형태는 아예 무시되고(#4046), (3) 호출자 abort reason·백오프 중 cancel이 Bun.sleep 경로에서 제대로 안 살아난다(#4047). xAI 토큰 refresh는 429/5xx를 최대 3회 재시도하는데, 대기 시간이 틀리면 바로 다음 실패나 불필요한 즉시 재시도로 이어진다. tip #4058 wp4는 catalog/runtime/service 쪽이고, 이 스택은 oauth 재시도 계약이라 방향이 다르다.

이 PR이 하는 일은 세 갈래다. 첫째, combo failover에 있던 HTTP-date 파서를 src/lib/http-retry-after.ts로 빼서 parseRetryAfterMs(..., { maxMs }) 공용 leaf로 만든다. failover는 MAX_COOLDOWN_MS를 넘기고, xAI 쪽은 MAX_RETRY_DELAY_MS = 60_000 캡을 쓴다. 둘째, postXaiToken의 sleep을 abort-aware로 바꾸고(waitForRetry가 custom sleep과 abort를 레이스), abort reason(null 포함)을 보존한다. 셋째, readTokenError가 JSON SyntaxError만 삼켜 malformed body를 non-fatal로 두고, 테스트 tests/providers/xai/xai-oauth-retry.test.ts에 소수 초·HTTP-date·60s 캡·백오프 중 abort·null reason 등 케이스를 크게 늘렸다. 본문 검증 주장(bun test 여러 스위트, typecheck, privacy:scan)도 있다.

다만 머지 전에 게이트가 막고 있다. hygiene가 unsponsored_surface로 실패했다(src/oauth/xai.ts는 인증 표면). enforce-target도 fail이다. #4065와 같은 파일이라 한쪽이 먼저 랜딩하면 다른 쪽은 rebase가 필요하다. 로컬 파서와 lib 파서가 숫자 경로를 이중으로 다루므로(선행 점 .5는 xAI 로컬 정규식, HTTP-date는 lib) 유지 비용이 조금 있다. DRAFT + checklist는 체크되어 있으나 Ready로 올리려면 hygiene 해제가 먼저다.

라인 98 근처(HEAD retryDelay) - 현재 dev는 정수 초만 읽고 2초로 자른다. 이 PR이 고치는 바로 그 버그다.
src/lib/http-retry-after.ts - failover 파서를 leaf로 옮긴 것은 맞다. xAI가 같은 leaf를 maxMs=60s로 재사용하는 방향도 일관된다.
src/oauth/xai.ts parseRetryAfterMs 로컬 래퍼 - 숫자/선행점 경로를 lib와 한 번 더 나눠 둔다. 동작은 테스트로 잠겼지만, 장기적으로는 lib 한곳으로 합치는 편이 덜 헷갈린다.
src/oauth/xai.ts waitForRetry - custom sleep이 signal을 무시해도 abort로 끊기게 한 레이스는 #4047에 맞다. 다만 분기가 많아서 이후 수정 때 회귀 위험이 있다(테스트가 그걸 막는 역할).
intake: hygiene-blocked / unsponsored_surface - 인증 표면이라 메인테이너 스폰서 없이는 머지 게이트를 통과하지 못한다.
#4065와 파일 충돌 - 엔드포인트 allow-list와 Retry-After는 이슈가 갈리지만 같은 xai.ts다. 랜딩 순서를 정해야 한다.

메인테이너의 판단이 필요한 지점

너의 추천
hygiene 스폰서(또는 maintainer carry) 후 #4060을 #4065보다 먼저 머지하는 쪽을 권한다. 닫는 이슈가 세 개이고 테스트 면적이 크며, #4048 보안 follow-up은 의도적으로 범위 밖이라 충돌 면만 관리하면 된다. DRAFT를 Ready로 올린 뒤 CI 그린을 확인하고 랜딩한다. types/config 분할과는 무관하니 close-don't-rebase 대상이 아니다.

이 댓글은 grok-bot이 작성했습니다

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working intake: hygiene-blocked Deterministic PR hygiene checks failed

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants